﻿using HPSocket.WebSocket;
using System.Net.Sockets;
using System.Reflection.Emit;
using HPSocket;
using IntelligentGateway.Model;
using Newtonsoft.Json;
using IntelligentGateway.Tools;
namespace IntelligentGateway.Services
{
    public delegate void OnWSTextHandler(HPSocket.IWebSocketAgent sender, IntPtr connId, byte[] data);
    public class WebSocketClient
    {
        WebSocketAgent _webSocketAgent;
        string _projectKey = string.Empty;
        volatile bool _isClose = false;
        byte[] pongData = null;
        public event OnWSTextHandler OnWSText;
        private IntPtr _connId;
        public IntPtr ConnID
        {
            get { return _connId; }
        }
        public bool IsConnected
        {
            get { return _webSocketAgent.HasStarted; }
        }       
        public WebSocketClient(string Host)
        {
            _webSocketAgent = new WebSocketAgent(Host);    
            _webSocketAgent.IgnoreCompressionExtensions = true;
            _webSocketAgent.OnOpen += _webSocketAgent_OnOpen;
            _webSocketAgent.OnClose += _webSocketAgent_OnClose;
            _webSocketAgent.OnMessage += _webSocketAgent_OnMessage;
            _webSocketAgent.OnPing += _webSocketAgent_OnPing;          
            
        }     
        private HPSocket.HandleResult _webSocketAgent_OnMessage(HPSocket.IWebSocketAgent sender, IntPtr connId, bool final, HPSocket.WebSocket.OpCode opCode, byte[] mask, byte[] data)
        {
            if (opCode == HPSocket.WebSocket.OpCode.Text)
            {
                if (OnWSText != null)
                {
                    OnWSText(sender, connId, data);
                }
                         
            }
            return HandleResult.Ok;
        }
        public bool Start()
        {
            bool success = true;
            if (!_webSocketAgent.HasStarted)
            {
                success = _webSocketAgent.Start();
            }
            if (success)
            {
                try
                {
                    _webSocketAgent.Connect();
                }
                catch (Exception e)
                {
#if TEST
                    Log.Debug("websocket Connect:" + e.ToString());
#endif
                    success = false;
                    
                }               
            }
            else
            {
                success = false;
            }

#if TEST
            Log.Debug("websocket:" + success);
#endif
            return success;
        }


        private void _webSocketAgent_OnPing(HPSocket.IWebSocketAgent sender, IntPtr connId, byte[] data)
        {
#if DEBUG
            Log.Debug($"WebSocketAgent_OnPing:{connId},data:{System.Text.Encoding.UTF8.GetString(data)}");     
#endif
            Console.WriteLine($"WebSocketAgent_OnPing:{connId},data:{System.Text.Encoding.UTF8.GetString(data)}");            
        }
        private HPSocket.HandleResult _webSocketAgent_OnClose(HPSocket.IWebSocketAgent sender, IntPtr connId, HPSocket.SocketOperation socketOperation, int errorCode)
        {
#if DEBUG
            Log.Debug($"OnClose({connId}), socket operation: {socketOperation}, error code: {errorCode}");
            Console.WriteLine($"OnClose({connId}), socket operation: {socketOperation}, error code: {errorCode}");

#endif           
            this.Start();
            return HandleResult.Ok;//重连机制。
        }
        public bool SendData(byte[] data)
        {
            bool succcess = _webSocketAgent.Send(_connId, HPSocket.WebSocket.OpCode.Text, data, data.Length);
            return succcess;
        }
        private HPSocket.HandleResult _webSocketAgent_OnOpen(HPSocket.IWebSocketAgent sender, IntPtr connId)
        {
#if DEBUG
            Log.Debug($"_webSocketAgent_OnOpen:{connId}");

#endif 
            Console.WriteLine($"_webSocketAgent_OnOpen:{connId}");
            _connId = connId;               
            return HandleResult.Ok;
        }       
    }
}
